/****************************************************************************\
 * @file    BR_Usart.h
 * @author  张伦玮,傅帅
 * @date    2019/12/24
 * @brief   串口通讯，可选是否使用DMA
 *          示例:  ***** 初始化 *****
 *                 BR_vUsartInit(2, 115200, 128, 2, OnRecvFunc);
 *                 BR_vUsartInitWithDMA(2, 115200, 128, 2, 128, 3, OnRecvFunc);
 *                 BR_vUsartInitWithDMA_OnlyTx(2, 115200, 128, 2, 2, OnRecvFunc);
 *                 BR_vUsartInitWithDMA_OnlyRx(2, 115200, 128, 128, 2, OnRecvFunc);
 *                 ***** 发送 *****
 *                 BR_iPrintf(2, "Hello World!");
 *                 BR_iSend(2, pStr, StrLen);
 *                 ***** 接收 *****
 *                 自定义 void OnRecvFunc(uint8_t *pData, uint32_t Len);并作为初始化参数
 ******************************************************************************
 * @attent   【注意，本库使用动态内存分配，.s文件中堆空间不应低于设置的总缓冲区大小】
 ****************************************************************************/
#ifndef BR_USART_H
#define BR_USART_H

#include "stm32f4xx.h"

/* 只用DMA发送，不需指定接收缓冲区大小 */
#define BR_vUsartInitWithDMA_OnlyTx(UsartNum, Bound, TxBuffSize, TxPrio,             RxPrio, vOnRecv) \
    BR_vUsartInitWithDMA       (UsartNum, Bound, TxBuffSize, TxPrio, 0,          RxPrio, vOnRecv)
/* 只用DMA接收，不需指定DMA发送完成中断优先级 */
#define BR_vUsartInitWithDMA_OnlyRx(UsartNum, Bound, TxBuffSize,         RxBuffSize, RxPrio, vOnRecv) \
    BR_vUsartInitWithDMA       (UsartNum, Bound, TxBuffSize, -1, RxBuffSize, RxPrio, vOnRecv)

typedef struct _BR_Usart_t      // 存一些函数接口
{
    void ( *vOnRecv )(uint8_t* pData, uint32_t Len);

    USART_TypeDef *USARTx;      // 串口号
    uint8_t     *pTxBuff;       // DMA发送缓冲区
    uint32_t TxBuffSize;        // 缓冲区大小(Byte)
    uint8_t     *pRxBuff;           // 串口接收数据的缓冲区
    uint32_t RxBuffSize;        // 缓冲区大小
    uint8_t DMA_Occupied;           // 标志DMA发送时是否发完
    uint8_t UseDMA_Send;            // 标志是否使用DMA发送
    uint32_t TxDMA_Flag;            // DMA中断状态标志
    uint32_t RxDMA_Flag;
    DMA_Stream_TypeDef *TxDMA_Stream;
    DMA_Stream_TypeDef *RxDMA_Stream;
}BR_Usart_t;

void BR_vUsartInit(uint8_t UsartNum, uint32_t Bound, uint32_t TxBuffSize, uint8_t RxPrio, void ( *vOnRecv )(uint8_t * pData, uint32_t Len));
void BR_vUsartInitWithDMA(uint8_t UsartNum, uint32_t Bound,
                          uint32_t TxBuffSize, int8_t TxPrio,
                          uint32_t RxBuffSize, int8_t RxPrio, void ( *vOnRecv )(uint8_t * pData, uint32_t Len));
int BR_iPrintf(uint8_t UsartNum, const char *Format, ...);
int BR_iSend(uint8_t UsartNum, uint8_t *pData, uint32_t Len);

void vVoidFunc(uint8_t * pData, uint32_t Len);  // 不需接收时可将回调设为此函数

#endif
